Imports System.Text
Imports System.IO

Namespace Core.Modules

    Public Class CategoryTranslator
        Inherits Translator


        Public Overrides Function Export() As Boolean
            Dim result As Boolean = True

            StatusMessage("Logging Into Web Store")
            Dim t As New BVweb.AuthenticationToken
            If WebServiceUtilities.Login(t) = False Then
                MsgBox("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                Return False
            End If

            StatusMessage("Getting List of Categories")
            Dim svc As New BVweb.WebServices3
            svc.Url = Helpers.FullServiceUrl
            Dim rows As Integer = 0
            ' Bug in SP1 prevents us from using "FindAll" so this hack gets everything within reason
            Dim cats() As BVweb.Category = svc.Catalog_Category_FindChildren_WithPaging(t, "-1", 0, 32000, rows)

            If cats IsNot Nothing Then
                StatusMessage("Exporting Categories")
                If cats.Length < 1 Then
                    StatusMessage("No Categories were Returned")
                    Return False
                End If
                RenderExport(cats)
            Else
                MsgBox("No categories were returned from the store. Unable to export.")
                Return False
            End If

            Return result
        End Function

        Public Overrides Function Import(ByVal lines() As String, ByVal cols() As MappedColumn) As Boolean
            Dim result = True

            Logging.WriteLine("Logging into store for Import...")
            StatusMessage("Loggin Into Store for Import...")
            Dim t As New BVweb.AuthenticationToken
            If WebServiceUtilities.Login(t) = False Then
                Logging.WriteLine("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                MsgBox("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                Return False
            Else
                Logging.WriteLine("Successfully logged into store")
            End If
            Dim svc As New BVweb.WebServices3
            svc.Url = Helpers.FullServiceUrl

            Logging.WriteLine("Processing " & lines.Length & " lines")
            For i As Integer = 1 To lines.Length - 1
                StatusMessage("Importing Item " & (i + 1))
                ImportItem(lines(i), cols, svc, t)
            Next           

            Logging.WriteLine("Finished with Import!")
            StatusMessage("Finished with Import!")

            Return result
        End Function

        Private Sub ImportItem(ByVal l As String, ByVal cols() As MappedColumn, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            Dim data() As String = l.Split(vbTab)
            If data IsNot Nothing Then
                Try

                    Dim updateMode As Boolean = False
                    Dim bvin As String = data(0).Trim
                    If bvin = "new" Then
                        bvin = String.Empty
                    End If

                    Dim c As BVweb.Category = svc.Catalog_Category_FindByBvin(t, bvin)
                    If c.Bvin = bvin Then
                        If bvin <> String.Empty Then
                            updateMode = True
                        Else
                            c.Bvin = System.Guid.NewGuid.ToString()
                        End If
                    Else
                        c.Bvin = bvin
                    End If

                    For i As Integer = 0 To data.Length - 1
                        ParseField(data(i), cols(i).ColumnName, c)
                    Next

                    Dim result As Boolean = False
                    StatusMessage("Saving Category " & c.Name)
                    If updateMode Then
                        result = svc.Catalog_Category_Update(t, c)
                        UpdateCustomURL(c, svc, t)
                    Else
                        result = svc.Catalog_Category_Insert(t, c)
                        AddCustomURL(c, svc, t)
                    End If

                    If result Then
                        If updateMode Then
                            Logging.WriteLine("Updated Category " & c.Name)
                        Else
                            Logging.WriteLine("Created Category " & c.Name)
                        End If
                    Else
                        If updateMode Then
                            Logging.WriteLine("ERROR: Failed to update Category " & c.Name)
                        Else
                            Logging.WriteLine("ERROR: Failed to create Category " & c.Name)
                        End If
                    End If
                Catch ex As Exception
                    Logging.WriteLine("EXCEPTION: From Import Item: " & ex.Message & "|" & ex.StackTrace)
                End Try
            End If
        End Sub

        Private Sub UpdateCustomURL(ByRef c As BVweb.Category, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            If c.RewriteUrl.Trim IsNot Nothing Then
                Dim cURL As BVweb.CustomUrl = svc.Content_CustomUrl_FindBySystemData(t, c.Bvin.ToString)
                If cURL.RequestedUrl <> c.RewriteUrl Then
                    cURL.RequestedUrl = c.RewriteUrl
                    svc.Content_CustomUrl_Update(t, cURL)
                End If
            End If
        End Sub

        Private Sub AddCustomURL(ByRef c As BVweb.Category, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            If c.RewriteUrl.Trim IsNot Nothing Then
                Dim cURL As BVweb.CustomUrl = New BVweb.CustomUrl
                cURL.Bvin = System.Guid.NewGuid.ToString()
                cURL.SystemUrl = True
                cURL.SystemData = c.Bvin
                cURL.RequestedUrl = c.RewriteUrl.Trim
                cURL.RedirectToUrl = svc.Utilities_UrlRewriter_BuildPhysicalUrlForCategory(t, c, "")
                svc.Content_CustomUrl_Insert(t, cURL)
            End If
        End Sub

        Private Sub ParseField(ByVal fieldData As String, ByVal columnName As String, ByRef c As BVweb.Category)
            Select Case columnName
                Case "parentid"
                    c.ParentId = MapperUtils.ParseFieldString(fieldData, c.ParentId)
                Case "name"
                    c.Name = MapperUtils.ParseFieldString(fieldData, c.Name)
                Case "description"
                    c.Description = MapperUtils.ParseFieldString(fieldData, c.Description)
                Case "showintopmenu"
                    c.ShowInTopMenu = MapperUtils.ParseFieldBoolean(fieldData, c.ShowInTopMenu)
                Case "templatename"
                    c.TemplateName = MapperUtils.ParseFieldString(fieldData, c.TemplateName)
                Case "imageurl"
                    c.ImageUrl = MapperUtils.ParseFieldString(fieldData, c.ImageUrl)
                Case "criteria"
                    c.Criteria = MapperUtils.ParseFieldString(fieldData, c.Criteria)
                Case "hidden"
                    c.Hidden = MapperUtils.ParseFieldBoolean(fieldData, c.Hidden)
                Case "bannerimageurl"
                    c.BannerImageUrl = MapperUtils.ParseFieldString(fieldData, c.BannerImageUrl)
                Case "rewriteurl"
                    c.RewriteUrl = MapperUtils.ParseFieldString(fieldData, c.RewriteUrl)
                Case "keywords"
                    c.Keywords = MapperUtils.ParseFieldString(fieldData, c.Keywords)
                Case "showtitle"
                    c.ShowTitle = MapperUtils.ParseFieldBoolean(fieldData, c.ShowTitle)
                Case "metatitle"
                    c.MetaTitle = MapperUtils.ParseFieldString(fieldData, c.MetaTitle)
                Case "metakeywords"
                    c.MetaKeywords = MapperUtils.ParseFieldString(fieldData, c.MetaKeywords)
                Case "metadescription"
                    c.MetaDescription = MapperUtils.ParseFieldString(fieldData, c.MetaDescription)
                Case "menuoffimageurl"
                    c.MenuOffImageUrl = MapperUtils.ParseFieldString(fieldData, c.MenuOffImageUrl)
                Case "menuonimageurl"
                    c.MenuOnImageUrl = MapperUtils.ParseFieldString(fieldData, c.MenuOnImageUrl)
                Case "custompageid"
                    c.CustomPageId = MapperUtils.ParseFieldString(fieldData, c.CustomPageId)
                Case "custompageopeninnewwindow"
                    c.CustomPageOpenInNewWindow = MapperUtils.ParseFieldBoolean(fieldData, c.CustomPageOpenInNewWindow)
                Case "custompageurl"
                    c.CustomPageUrl = MapperUtils.ParseFieldString(fieldData, c.CustomPageUrl)
                Case "precontentcolumnid"
                    c.PreContentColumnId = MapperUtils.ParseFieldString(fieldData, c.PreContentColumnId)
                Case "postcontentcolumnid"
                    c.PostContentColumnId = MapperUtils.ParseFieldString(fieldData, c.PostContentColumnId)
                Case "pretransformdescription"
                    c.PreTransformDescription = MapperUtils.ParseFieldString(fieldData, c.PreTransformDescription)
            End Select
        End Sub

        Private Sub RenderExport(ByVal data() As BVweb.Category)
            Dim sb As New StringBuilder

            WriteHeaders(sb)
            For i As Integer = 0 To data.Length - 1
                StatusMessage("Exporting Category " & (i + 1) & " of " & data.Length)
                WriteItem(data(i), sb)
            Next

            Dim v As New ExportView
            v.OutputText = sb.ToString
            v.ShowDialog()
            v.Dispose()
        End Sub

        Private Sub WriteHeaders(ByRef sb As StringBuilder)
            StatusMessage("Writing Headers")

            sb.Append("Bvin")
            sb.Append(vbTab)
            sb.Append("ParentId")
            sb.Append(vbTab)
            sb.Append("Name")
            sb.Append(vbTab)
            sb.Append("Description")
            sb.Append(vbTab)
            sb.Append("ShowInTopMenu")
            sb.Append(vbTab)
            sb.Append("SourceType")
            sb.Append(vbTab)
            sb.Append("TemplateName")
            sb.Append(vbTab)
            sb.Append("ImageUrl")
            sb.Append(vbTab)
            sb.Append("Criteria")
            sb.Append(vbTab)
            sb.Append("Hidden")
            sb.Append(vbTab)
            sb.Append("BannerImageUrl")
            sb.Append(vbTab)
            sb.Append("RewriteUrl")
            sb.Append(vbTab)
            sb.Append("Keywords")
            sb.Append(vbTab)
            sb.Append("ShowTitle")
            sb.Append(vbTab)
            sb.Append("MetaTitle")
            sb.Append(vbTab)
            sb.Append("MetaKeywords")
            sb.Append(vbTab)
            sb.Append("MetaDescription")
            sb.Append(vbTab)
            sb.Append("MenuOffImageUrl")
            sb.Append(vbTab)
            sb.Append("MenuOnImageUrl")
            sb.Append(vbTab)
            sb.Append("CustomPageId")
            sb.Append(vbTab)
            sb.Append("CustomPageOpenInNewWindow")
            sb.Append(vbTab)
            sb.Append("CustomPageUrl")
            sb.Append(vbTab)
            sb.Append("PreContentColumnId")
            sb.Append(vbTab)
            sb.Append("PostContentColumnId")
            sb.Append(vbTab)
            sb.Append("PreTransformDescription")
            sb.Append(vbTab)
            sb.Append("LatestProductCount")
            sb.Append(vbTab)
            sb.Append("LastUpdated")
            sb.Append(System.Environment.NewLine)

        End Sub

        Private Sub WriteItem(ByVal c As BVweb.Category, ByRef sb As StringBuilder)
            sb.Append(c.Bvin)
            sb.Append(vbTab)
            sb.Append(c.ParentId)
            sb.Append(vbTab)
            sb.Append(SafeString(c.Name))
            sb.Append(vbTab)
            sb.Append(SafeString(c.Description))
            sb.Append(vbTab)
            sb.Append(SafeBool(c.ShowInTopMenu))
            sb.Append(vbTab)
            sb.Append(SafeSourceType(c.SourceType))
            sb.Append(vbTab)
            sb.Append(SafeString(c.TemplateName))
            sb.Append(vbTab)
            sb.Append(SafeString(c.ImageUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.Criteria))
            sb.Append(vbTab)
            sb.Append(SafeBool(c.Hidden))
            sb.Append(vbTab)
            sb.Append(SafeString(c.BannerImageUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.RewriteUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.Keywords))
            sb.Append(vbTab)
            sb.Append(SafeBool(c.ShowTitle))
            sb.Append(vbTab)
            sb.Append(SafeString(c.MetaTitle))
            sb.Append(vbTab)
            sb.Append(SafeString(c.MetaKeywords))
            sb.Append(vbTab)
            sb.Append(SafeString(c.MetaDescription))
            sb.Append(vbTab)
            sb.Append(SafeString(c.MenuOffImageUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.MenuOnImageUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.CustomPageId))
            sb.Append(vbTab)
            sb.Append(SafeBool(c.CustomPageOpenInNewWindow))
            sb.Append(vbTab)
            sb.Append(SafeString(c.CustomPageUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(c.PreContentColumnId))
            sb.Append(vbTab)
            sb.Append(SafeString(c.PostContentColumnId))
            sb.Append(vbTab)
            sb.Append(SafeString(c.PreTransformDescription))
            sb.Append(vbTab)
            sb.Append(SafeString(c.LatestProductCount.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(c.LastUpdated.ToString))
            sb.Append(System.Environment.NewLine)
        End Sub

        Private Function SafeString(ByVal input As String) As String
            Dim result As String = input.Replace(vbTab, "")
            Return result
        End Function

        Private Function SafeBool(ByVal input As Boolean) As String
            If input = True Then
                Return "True"
            Else
                Return "False"
            End If
        End Function

        Private Function SafeSourceType(ByVal input As BVweb.CategorySourceType) As String
            Dim result As String = "Manual"
            Select Case input
                Case BVweb.CategorySourceType.ByRules
                    result = "By Rules"
                Case BVweb.CategorySourceType.CustomLink
                    result = "Custom Link"
                Case BVweb.CategorySourceType.CustomPage
                    result = "Custom Page"
                Case BVweb.CategorySourceType.Manual
                    result = "Manual"
            End Select
            Return result
        End Function

    End Class

End Namespace